{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DSP Filter Design\n",
    "\n",
    "## Required Packages\n",
    "\n",
    "Must add \"DSP\" package:\n",
    "```\n",
    "Pkg.add(\"DSP\")\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "using DSP\n",
    "include(\"DSPFilters.jl\")\n",
    "using InspectDR\n",
    "using NumericIO\n",
    "using Colors\n",
    "\n",
    "#Convenience aliases:\n",
    "SI(x) = formatted(x, :SI, ndigits=3)\n",
    "\n",
    "#When MIME\"image/svg+xml\" is disabled, Jupyter eventually requests PNG inline graphics:\n",
    "#(SVG outputs do not render well in notebooks for some reason...)\n",
    "InspectDR.defaults.rendersvg = false\n",
    ";"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Setup: Interact, Reactive, and Signals\n",
    "(Also create initial plot object)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "using Interact, Reactive\n",
    "\n",
    "ftypelist = [\"Highpass\", \"Lowpass\", \"Bandstop\", \"Bandpass\"]\n",
    "fimpllist = [\"Butterworth\", \"Elliptic\", \"ChebyshevPass\", \"ChebyshevStop\"]\n",
    "\n",
    "ftype = Signal(String, \"Lowpass\") #Filter type\n",
    "fimpl = Signal(String, \"Elliptic\") #Filter implementation\n",
    "fmax = Signal(Float64, 500) #Maximum plot frequency\n",
    "forder = Signal(Int, 6) #Filter order\n",
    "fl = Signal(Float64, 300) #Low frequency point\n",
    "fh = Signal(Float64, 400) #High frequency point\n",
    "rpass = Signal(Float64, 5) #Pass-band ripple\n",
    "rstop = Signal(Float64, 40) #Stop-band ripple\n",
    "pobj = DSPFilters.newplot() #Create initial plot object\n",
    ";"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Interact/Reactive Control: Plot limits\n",
    "\n",
    "\n",
    "## TODO"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "txt_fmax = textbox(value(fmax), label=\"max freq\") #This one does not cause hangups\n",
    "fmax = signal(txt_fmax) #Hack to get fmax/txt_fmax working\n",
    "map(display, [txt_fmax])\n",
    ";"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Interact/Reactive Control: Inline Plots\n",
    "Use sliders/text boxes to change filter parameters.\n",
    "\n",
    "## TODO\n",
    "\n",
    " - Make fl & fh sliders relative to fmax?\n",
    " - Disable unused parameters (depending on filter implementation)\n",
    " - Look for off by 1 errors (esp. for FFT vector lengths, etc).\n",
    " - Other details look not quite right (@ notches, phase response, ...)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "tgl_ftype = togglebuttons(ftypelist, value_label=value(ftype), signal=ftype)\n",
    "tgl_fimpl = dropdown(fimpllist, value_label=value(fimpl), signal=fimpl)\n",
    "map(display, [tgl_ftype, tgl_fimpl])\n",
    "\n",
    "#Main filter parameters:\n",
    "sld_order = slider(2:1:30, value=value(forder), label=\"Filter order\", signal = forder)\n",
    "sld_rpass = slider(0.1:.1:20, value=value(rpass), label=\"Pass-band ripple (dB)\", signal = rpass)\n",
    "sld_rstop = slider(5:.1:200, value=value(rstop), label=\"Stop-band ripple (dB)\", signal = rstop)\n",
    "sld_fl = slider(10:10:1e3, value=value(fl), label=\"Low frequency (Hz)\", signal = fl)\n",
    "sld_fh = slider(10:10:1e3, value=value(fh), label=\"High frequency (Hz)\", signal = fh)\n",
    "map(display, [sld_order, sld_rpass, sld_rstop, sld_fl, sld_fh])\n",
    "\n",
    "#Widget-controlled plot:\n",
    "updater_plot = map(fmax, ftype, fimpl, forder, fl, fh, rpass, rstop) do _fmax, _ftype, _fimpl, _forder, _fl, _fh, _rpass, _rstop\n",
    "    _filttypeid = Symbol(lowercase(_ftype))\n",
    "    _filtimplid = Symbol(lowercase(_fimpl))\n",
    "    DSPFilters.update(pobj, _fmax, _filttypeid, _filtimplid, _forder, _fl, _fh, _rpass, _rstop)\n",
    "end\n",
    "display(updater_plot)\n",
    ";"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Interact/Reactive Control: Inspect/Gtk GUI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "gtkgui = display(InspectDR.GtkDisplay(), pobj) #Display plot in Gtk GUI.\n",
    "\n",
    "#Refresh GUI when plot changes:\n",
    "updater_gtkgui = map((p)->InspectDR.refresh(gtkgui), updater_plot)\n",
    "\n",
    "#Re-display GUI controls, for convenience:\n",
    "#map(display, widgetlist)\n",
    ";"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Demo Complete!"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Julia 0.6.0",
   "language": "julia",
   "name": "julia-0.6"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "0.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
